package Controllers;

import Configs.Config;
import GUIs.f_nhanvien_chunhatro_sua;
import GUIs.f_nhanvien_chunhatro_them;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;
import com.db4o.query.Query;
import java.awt.Component;
import java.util.Date;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import models.ChuNhaTro;
import models.DiaChi;
import models.GioiTinh;

public class ChuNhaTroController {

    private final Config conn;
    private BieuThucChinhQuy btcq;
    private MyTableFormat myFormat;

    public ChuNhaTroController(Config conn) {
        this.conn = conn;
    }

    public ChuNhaTro getWithCMND(String cmnd) {
        return this.conn.getConn().query(new Predicate<ChuNhaTro>() {
            @Override
            public boolean match(ChuNhaTro chunhatro) {
                return (chunhatro.getCMND().equals(cmnd));
            }
        }).next();
    }

    public void Show(JTable tbchunhatro, String txttim) {
        this.myFormat = new MyTableFormat();
        DefaultTableModel model = (DefaultTableModel) tbchunhatro.getModel();
        int stt = 0;
        if (txttim == null) {
            ObjectSet<ChuNhaTro> chunhatros = this.conn.getConn().query(new Predicate<ChuNhaTro>() {
                @Override
                public boolean match(ChuNhaTro chunhatro) {
                    return !chunhatro.getIsDel();
                }
            });
            for (ChuNhaTro chunhatro : chunhatros) {
                DiaChi dc = chunhatro.getDiachi();
                Object[] row = {++stt, chunhatro.getCMND(), chunhatro.getHoten(), "<html>- Số nhà: " + dc.getSonha() + "<br/>- Hẻm: " + dc.getHem() + "<br/>- Đường: " + dc.getDuong() + "<br/>- Quận (huyện):" + dc.getQuanhuyen() + "<br/>- Tỉnh (thành phố): " + dc.getTinhtp() + "</html>"};
                model.addRow(row);
            }
        } else {
            Query query = this.conn.getConn().query();
            query.constrain(ChuNhaTro.class);
            query.descend("CMND").constrain(txttim).like().endsWith(true).startsWith(true).or(query.descend("hoten").constrain(txttim).like().endsWith(true).startsWith(true));
            query.descend("isDel").constrain(false).equal();
            ObjectSet<ChuNhaTro> chunhatros = query.execute();
            for (ChuNhaTro chunhatro : chunhatros) {
                DiaChi dc = chunhatro.getDiachi();
                Object[] row = {++stt, chunhatro.getCMND(), chunhatro.getHoten(), "<html>- Số nhà: " + dc.getSonha() + "<br/>- Hẻm: " + dc.getHem() + "<br/>- Đường: " + dc.getDuong() + "<br/>- Quận (huyện):" + dc.getQuanhuyen() + "<br/>- Tỉnh (thành phố): " + dc.getTinhtp() + "</html>"};
                model.addRow(row);
            }
        }

        this.myFormat.resizeFitRows(tbchunhatro);
    }

    public boolean Add(f_nhanvien_chunhatro_them them_chunhatro) {
        String cmnd = them_chunhatro.tfcmnd.getText();
        String hoten = XuLyChuoi.inHoaChuDauChuoi(them_chunhatro.tfhoten.getText());
        String gioitinh = them_chunhatro.cbbgioitinh.getSelectedItem().toString();
        Date ngaysinh = them_chunhatro.datengaysinh.getDate();
        String sdt = them_chunhatro.tfsdt.getText();
        String sonha = them_chunhatro.tfsonha.getText();
        String hem = XuLyChuoi.inHoaChuDauChuoi(them_chunhatro.tfhem.getText());
        String duong = XuLyChuoi.inHoaChuDauChuoi(them_chunhatro.tfduong.getText());
        String quanhuyen = XuLyChuoi.inHoaChuDauChuoi(them_chunhatro.tfquanhuyen.getText());
        String tinhtp = XuLyChuoi.inHoaChuDauChuoi(them_chunhatro.tftinhtp.getText());

        this.btcq = new BieuThucChinhQuy(cmnd, "^[0-9]{9,15}$");
        if (!this.btcq.isBoolean()) {
            JOptionPane.showMessageDialog(them_chunhatro, "CMND không hợp lệ.\nCảnh báo: CMND chỉ chứa các ký tự số [0-9] dài trong khoảng [9-15] ký tự.", "Thông báo", JOptionPane.ERROR_MESSAGE);
            them_chunhatro.tfcmnd.requestFocus();
        } else {
            this.btcq.setBtchinhquy("[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
            this.btcq.setChuoikt(hoten);
            if (!this.btcq.isBoolean()) {
                JOptionPane.showMessageDialog(them_chunhatro, "Họ tên không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                them_chunhatro.tfhoten.requestFocus();
            } else if (gioitinh.equals("Chọn")) {
                JOptionPane.showMessageDialog(them_chunhatro, "Vui lòng chọn giới tính chủ nhà trọ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                them_chunhatro.cbbgioitinh.requestFocus();
            } else if (!DateNTime.checkTuoi(ngaysinh)) {
                JOptionPane.showMessageDialog(them_chunhatro, "Ngày tháng năm sinh không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                them_chunhatro.datengaysinh.requestFocus();
            } else {
                this.btcq.setBtchinhquy("^[0-9]{9,15}$");
                this.btcq.setChuoikt(sdt);
                if (!this.btcq.isBoolean()) {
                    JOptionPane.showMessageDialog(them_chunhatro, "Số điện thoại không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                    them_chunhatro.tfsdt.requestFocus();
                } else {
                    this.btcq.setBtchinhquy("^[A-Za-z0-9]{1,10}$");
                    this.btcq.setChuoikt(sonha);
                    if (!this.btcq.isBoolean()) {
                        JOptionPane.showMessageDialog(them_chunhatro, "Số nhà không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                        them_chunhatro.tfsonha.requestFocus();
                    } else {
                        this.btcq.setBtchinhquy("[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
                        this.btcq.setChuoikt(hem);
                        if (!this.btcq.isBoolean()) {
                            JOptionPane.showMessageDialog(them_chunhatro, "Hẻm không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                            them_chunhatro.tfhem.requestFocus();
                        } else {
                            this.btcq.setBtchinhquy("[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
                            this.btcq.setChuoikt(duong);
                            if (!this.btcq.isBoolean()) {
                                JOptionPane.showMessageDialog(them_chunhatro, "Đường không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                                them_chunhatro.tfduong.requestFocus();
                            } else {
                                this.btcq.setBtchinhquy("[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
                                this.btcq.setChuoikt(quanhuyen);
                                if (!this.btcq.isBoolean()) {
                                    JOptionPane.showMessageDialog(them_chunhatro, "Quận huyện không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                                    them_chunhatro.tfquanhuyen.requestFocus();
                                } else {
                                    this.btcq.setBtchinhquy("[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
                                    this.btcq.setChuoikt(tinhtp);
                                    if (!this.btcq.isBoolean()) {
                                        JOptionPane.showMessageDialog(them_chunhatro, "Tỉnh thành phố không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                                        them_chunhatro.tftinhtp.requestFocus();
                                    } else {
                                        ObjectSet<ChuNhaTro> conflicts = this.conn.getConn().query(new Predicate<ChuNhaTro>() {

                                            @Override
                                            public boolean match(ChuNhaTro et) {
                                                return et.getCMND().equals(cmnd);
                                            }
                                        });
                                        if (conflicts.size() == 0) {
                                            ChuNhaTro themmoi = new ChuNhaTro(cmnd, hoten, (gioitinh.equals("Nam")) ? GioiTinh.Nam : GioiTinh.Nữ, sdt, ngaysinh);
                                            DiaChi dc = new DiaChi(sonha, hem, duong, quanhuyen, tinhtp);
                                            themmoi.setDiachi(dc);
                                            this.conn.getConn().store(themmoi);
                                            return true;
                                        } else {
                                            JOptionPane.showMessageDialog(them_chunhatro, "CMND này trùng với một người khác trong CSDL.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                                            them_chunhatro.tfcmnd.requestFocus();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    public boolean Edit(f_nhanvien_chunhatro_sua them_chunhatro) {
        String cmnd = them_chunhatro.tfcmnd.getText();
        String hoten = XuLyChuoi.inHoaChuDauChuoi(them_chunhatro.tfhoten.getText());
        String gioitinh = them_chunhatro.cbbgioitinh.getSelectedItem().toString();
        Date ngaysinh = them_chunhatro.datengaysinh.getDate();
        String sdt = them_chunhatro.tfsdt.getText();
        String sonha = XuLyChuoi.inHoaChuDauChuoi(them_chunhatro.tfsonha.getText());
        String hem = XuLyChuoi.inHoaChuDauChuoi(them_chunhatro.tfhem.getText());
        String duong = XuLyChuoi.inHoaChuDauChuoi(them_chunhatro.tfduong.getText());
        String quanhuyen = XuLyChuoi.inHoaChuDauChuoi(them_chunhatro.tfquanhuyen.getText());
        String tinhtp = XuLyChuoi.inHoaChuDauChuoi(them_chunhatro.tftinhtp.getText());

        this.btcq = new BieuThucChinhQuy(hoten, "[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
        this.btcq.setChuoikt(hoten);
        if (!this.btcq.isBoolean()) {
            JOptionPane.showMessageDialog(them_chunhatro, "Họ tên không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
            them_chunhatro.tfhoten.requestFocus();
        } else if (gioitinh.equals("Chọn")) {
            JOptionPane.showMessageDialog(them_chunhatro, "Vui lòng chọn giới tính chủ nhà trọ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
            them_chunhatro.cbbgioitinh.requestFocus();
        } else if (!DateNTime.checkTuoi(ngaysinh)) {
            JOptionPane.showMessageDialog(them_chunhatro, "Ngày tháng năm sinh không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
            them_chunhatro.datengaysinh.requestFocus();
        } else {
            this.btcq.setBtchinhquy("^[0-9]{9,15}$");
            this.btcq.setChuoikt(sdt);
            if (!this.btcq.isBoolean()) {
                JOptionPane.showMessageDialog(them_chunhatro, "Số điện thoại không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                them_chunhatro.tfsdt.requestFocus();
            } else {
                this.btcq.setBtchinhquy("^[A-Za-z0-9]{1,10}$");
                this.btcq.setChuoikt(sonha);
                if (!this.btcq.isBoolean()) {
                    JOptionPane.showMessageDialog(them_chunhatro, "Số nhà không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                    them_chunhatro.tfsonha.requestFocus();
                } else {
                    this.btcq.setBtchinhquy("[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
                    this.btcq.setChuoikt(hem);
                    if (!this.btcq.isBoolean()) {
                        JOptionPane.showMessageDialog(them_chunhatro, "Hẻm không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                        them_chunhatro.tfhem.requestFocus();
                    } else {
                        this.btcq.setBtchinhquy("[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
                        this.btcq.setChuoikt(duong);
                        if (!this.btcq.isBoolean()) {
                            JOptionPane.showMessageDialog(them_chunhatro, "Đường không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                            them_chunhatro.tfduong.requestFocus();
                        } else {
                            this.btcq.setBtchinhquy("[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
                            this.btcq.setChuoikt(quanhuyen);
                            if (!this.btcq.isBoolean()) {
                                JOptionPane.showMessageDialog(them_chunhatro, "Quận huyện không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                                them_chunhatro.tfquanhuyen.requestFocus();
                            } else {
                                this.btcq.setBtchinhquy("[^!@#$%^&*\\{\\}\\\\'\\\"]+$");
                                this.btcq.setChuoikt(tinhtp);
                                if (!this.btcq.isBoolean()) {
                                    JOptionPane.showMessageDialog(them_chunhatro, "Tỉnh thành phố không hợp lệ.", "Thông báo", JOptionPane.ERROR_MESSAGE);
                                    them_chunhatro.tftinhtp.requestFocus();
                                } else {
                                    ChuNhaTro edit = this.conn.getConn().query(new Predicate<ChuNhaTro>() {
                                        @Override
                                        public boolean match(ChuNhaTro et) {
                                            return et.getCMND().equals(cmnd);
                                        }
                                    }).next();
                                    DiaChi dc = new DiaChi(sonha, hem, duong, quanhuyen, tinhtp);
                                    edit.setHoten(hoten);
                                    edit.setGioitinh((gioitinh.equals("Nam")) ? GioiTinh.Nam : GioiTinh.Nữ);
                                    edit.setNgaysinh(ngaysinh);
                                    edit.setSdt(sdt);
                                    edit.setDiachi(dc);
                                    this.conn.getConn().store(edit);
                                    return true;
                                }
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    public boolean Delete(String cmnd) {
        ObjectSet<ChuNhaTro> xoa = this.conn.getConn().query(new Predicate<ChuNhaTro>() {
            @Override
            public boolean match(ChuNhaTro et) {
                return et.getCMND().equals(cmnd);
            }
        });

        while (xoa.hasNext()) {
            ChuNhaTro chuNhaTro = xoa.next();
            if (chuNhaTro.getDsnhatro().isEmpty()) {
                this.conn.getConn().delete(chuNhaTro);
            } else {
                chuNhaTro.setIsDel(true);
                this.conn.getConn().store(chuNhaTro);
            }
        }
        return true;
    }
}
